/**///////////////////////////////////////////////////////////////////////
// Progress.cpp: implementation of the CProgress class.
//
/**///////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Progress.h"


//--------------------------------------------------------------------
//Macro define
#define DEFAULT_MIN_LEVEL                0
#define DEFAULT_MAX_LEVEL                10
#define DEFAULT_CUR_LEVEL                0
#define DEFAULT_BKCOLOR                    RGB(128,128,128)
#define DEFAULT_BKMODE                    TRANSPARENT

//The interval between two level image
#define LEVEL_INTERVAL            4
//--------------------------------------------------------------------
/**///////////////////////////////////////////////////////////////////////
// Construction/Destruction
/**///////////////////////////////////////////////////////////////////////

CProgress::CProgress()
{
	memset(&m_rcWndPos,0,sizeof(m_rcWndPos));
	memset(&m_ImgValid,0,sizeof(m_ImgValid));
	memset(&m_ImgInvalid,0,sizeof(m_ImgInvalid));
	m_iMaxLevel = DEFAULT_MAX_LEVEL;
	m_iMinLevel = DEFAULT_MIN_LEVEL;
	m_iCurLevel = DEFAULT_CUR_LEVEL;
	m_hInst = NULL;
	m_crBkColor = DEFAULT_BKCOLOR;
	m_iBkMode = DEFAULT_BKMODE;
}

CProgress::~CProgress()
{
}


//-------------------------------------------------------------------
//Description:
//    Set the position
//-------------------------------------------------------------------
void CProgress::SetPosition(const RECT *prc)
{
	m_rcWndPos = *prc;
}


//-------------------------------------------------------------------
//Description:
//    Set the image information for valid
//-------------------------------------------------------------------
void CProgress::SetImgInfoValid(const DISPIMAGEINFO *pInfo)
{
	m_ImgValid = *pInfo;
}


//-------------------------------------------------------------------
//Description:
//    Set the image information for invalid
//-------------------------------------------------------------------
void CProgress::SetImgInfoInvalid(const DISPIMAGEINFO *pInfo)
{
	m_ImgInvalid = *pInfo;
}


//-------------------------------------------------------------------
//Description:
//    Set the range
//-------------------------------------------------------------------
BOOL CProgress::SetRange(int iMin, int iMax)
{
	if(iMin < 0 || iMax < 0 || iMin >= iMax)
	{
			return FALSE;
	}

	m_iMinLevel = iMin;
	m_iMaxLevel = iMax;

	return TRUE;
}



//-------------------------------------------------------------------
//Description:
//    Set the position
//-------------------------------------------------------------------
BOOL CProgress::SetLevel(int iLevel)
{
	if(iLevel < m_iMinLevel || iLevel > m_iMaxLevel)
	{
			return FALSE;
	}
	m_iCurLevel = iLevel;
	return TRUE;
}


//-------------------------------------------------------------------
//Description:
//    Draw the control
//-------------------------------------------------------------------
BOOL CProgress::Draw(HDC hdc)
{
	if(m_hInst == NULL)
	{
			return FALSE;
	}

	int iImgTotalWidth = (m_ImgValid.right - m_ImgValid.left) * (m_iMaxLevel - m_iMinLevel) + LEVEL_INTERVAL * (m_iMaxLevel - m_iMinLevel - 1);
	int iImgTotalHeight = m_ImgValid.bottom - m_ImgValid.top;

	//Create a DC that matches the device
	HBITMAP hBitmap = CreateCompatibleBitmap(hdc,iImgTotalWidth,iImgTotalHeight);
	HDC hdcMem = CreateCompatibleDC(hdc);
	//Select the bitmap into to the compatible device context
	HGDIOBJ hOldSel = SelectObject(hdcMem,hBitmap);



	//Draw the background
	//The frame color
	HPEN hPen=CreatePen(PS_SOLID,1,m_crBkColor);
	HPEN hOldPen=NULL;
	hOldPen=(HPEN)SelectObject(hdcMem,hPen);
	//the rect color
	HBRUSH hBrush = CreateSolidBrush(m_crBkColor);
	HGDIOBJ hOldBrush = SelectObject(hdcMem,hBrush);
	//Draw
	Rectangle(hdcMem,0,0,iImgTotalWidth + 1, iImgTotalHeight + 1);
	//Realse the resource
	SelectObject(hdcMem,hOldBrush);
	DeleteObject(hBrush);
	SelectObject(hdcMem,hOldPen);
	DeleteObject(hPen);




	//Draw the valid image
	//Create a DC that matches the device to draw the background bitmap
	HDC hdcBmp = CreateCompatibleDC(hdc);
	//Load the  bitmap
	HANDLE    hBmp = LoadImage(m_hInst,MAKEINTRESOURCE(m_ImgValid.imgID),IMAGE_BITMAP,0,0,0);
	//Select the bitmap into to the compatible device context
	HGDIOBJ hOldBmpSel = SelectObject(hdcBmp,hBmp);
	int i = 0, iPos_x = 0;
	for(i = m_iMinLevel + 1; i <= m_iCurLevel; i ++)
	{
			//Copy the bitmap image to the memory DC
			BitBlt(hdcMem,iPos_x,0,(m_ImgValid.right - m_ImgValid.left),(m_ImgValid.bottom - m_ImgValid.top),hdcBmp,m_ImgValid.left,m_ImgValid.top,SRCCOPY);
			iPos_x += (m_ImgValid.right - m_ImgValid.left) + LEVEL_INTERVAL;
	}
	//Delete the bmp
	DeleteObject(hBmp);


	//Draw the invalid image
	hBmp = LoadImage(m_hInst,MAKEINTRESOURCE(m_ImgInvalid.imgID),IMAGE_BITMAP,0,0,0);
	//Select the bitmap into to the compatible device context
	SelectObject(hdcBmp,hBmp);
	for(i = m_iCurLevel + 1; i <= m_iMaxLevel; i ++)
	{
			//Copy the bitmap image to the memory DC
			BitBlt(hdcMem,iPos_x,0,(m_ImgValid.right - m_ImgValid.left),(m_ImgValid.bottom - m_ImgValid.top),hdcBmp,m_ImgInvalid.left,m_ImgInvalid.top,SRCCOPY);
			iPos_x += (m_ImgValid.right - m_ImgValid.left) + LEVEL_INTERVAL;
	}
	//Delete the bmp
	DeleteObject(hBmp);



	if(m_iBkMode == TRANSPARENT)
	{
			TransparentImage(hdc,m_rcWndPos.left,m_rcWndPos.top,(m_rcWndPos.right - m_rcWndPos.left),(m_rcWndPos.bottom - m_rcWndPos.top),
				hdcMem,0,0,iImgTotalWidth,iImgTotalHeight,m_crBkColor);
	}
	else
	{
			StretchBlt(hdc,m_rcWndPos.left,m_rcWndPos.top,(m_rcWndPos.right - m_rcWndPos.left),(m_rcWndPos.bottom - m_rcWndPos.top),
				hdcMem,0,0,iImgTotalWidth,iImgTotalHeight,SRCCOPY);
	}
	//Restore original bitmap selection and destroy the memory DC
	SelectObject(hdcBmp,hOldBmpSel);
	SelectObject(hdcMem,hOldSel);
	DeleteObject(hBitmap);    
	DeleteDC(hdcBmp);
	DeleteDC(hdcMem);



	return TRUE;
}


//-------------------------------------------------------------------
//Description:
//    Set the hinstance
//-------------------------------------------------------------------
void CProgress::SetHinstance(HINSTANCE hInst)
{
	m_hInst = hInst;
}


//-------------------------------------------------------------------
//Description:
//    Set the background color
//-------------------------------------------------------------------
void CProgress::SetBkColor(COLORREF crColor)
{
	m_crBkColor = crColor;
}


//--------------------------------------------------------------------
//Description:
//    Set the background mode.If you choose the TRANSPARENT, the transparent
//color is the background color
//
//Parameters:
//    iMode: [in] The value is just like as follow:
//        OPAQUE      -- Background is filled with the current background color before the text, 
//                        hatched brush, or pen is drawn. 
//        TRANSPARENT -- Background remains untouched. 

//--------------------------------------------------------------------
BOOL CProgress::SetBkMode(int iMode)
{
	if(iMode == OPAQUE || iMode == TRANSPARENT)
	{
			m_iBkMode = iMode;
			return TRUE;
	}
	else
	{
			return FALSE;
	}
}